unit oAgentEnviroment;

interface

uses uOSPABA, oStatisticEventConstants;

type

  TSchedulerPedestrianArrivals = class(tScheduler)
    private
      aActorID: Integer;
    public
      constructor create(paID: Cardinal; paAgent: TAgent);
      procedure ProcessMessage(var paMessage:TMessageForm); override;
  end;

  TAgentEnviroment = class(TAgent)
    private
      aSchedulerPedestrianArrivals: TSchedulerPedestrianArrivals;
    public
      property SchedulerPedestrianArrivals:TSchedulerPedestrianArrivals read aSchedulerPedestrianArrivals write aSchedulerPedestrianArrivals;
      constructor create(paID: Cardinal; paSim: TSimulation; paParent:TAgent);
  end;

  TManagerEnviroment = class(TManager)
    public
      constructor create(paID: Cardinal;paAgent: TAgent;paString: String);
      procedure ProcessMessage(var paMessage: TMessageForm); override;
  end;

implementation

uses
  oArrivalsManager,oSimulation, oPedActor, Dialogs, SysUtils, oSink, oPedestrian, oSpawn, oStats;

{ TManagerEnviroment }

constructor TManagerEnviroment.create(paID: Cardinal; paAgent: TAgent;
  paString: String);
begin
  inherited create(paID,paAgent,paString);
end;

procedure TManagerEnviroment.ProcessMessage(var paMessage: TMessageForm);
begin
  with paMessage.MySim as TPedSimulation do
    case paMessage.Code of

      mcInitO: begin
        paMessage.Addressee := (MyAgent as TAgentEnviroment).SchedulerPedestrianArrivals;
        StartContinualAssistant(paMessage);
      end;

      mcOdchodCM: begin
        with MySim as TPedSimulation do
          begin
            if StatPeopleInModel <> nil then StatPeopleInModel.AddXY(StatPeopleInModel.LastVal - 1,CurrentTime);
            if (paMessage as TPSMessage).Actor.StatWaiting <> nil then begin
              (paMessage as TPSMessage).Actor.StatWaiting.EndWaiting(MySim.CurrentTime);
            end;

            (MySim as TPedSimulation).writeStaticticEvent(SE_WAITING_TIME,
                         (paMessage as TPSMessage).Actor.Pedestrian.GroupName,
                         (paMessage as TPSMessage).Actor.StatWaiting.WaitTime);


          end;
        (MyAgent as TAgentEnviroment).AddActor((paMessage as TPSMessage).Actor);
         (MySim as TPedSimulation).World.getLevel(((paMessage as TPSMessage).Actor.Pedestrian.Level)).
         deletePedestrian((paMessage as TPSMessage).Actor.Pedestrian, ((paMessage as TPSMessage).Actor.Target as TSink));

//        ((paMessage as TPSMessage).Actor.Target as TSink).ExitPedestrian((paMessage as TPSMessage).Actor.Pedestrian);
        (paMessage as TPSMessage).Actor.Pedestrian := nil;
        (paMessage as TPSMessage).Actor.Path := nil;
        (paMessage as TPSMessage).Actor.Free;
        (paMessage as TPSMessage).Actor := nil;
        paMessage.Free;
      end;

      mcPrichodC: begin
        with MySim as TPedSimulation do
          begin
            if StatPeopleInModel <> nil then StatPeopleInModel.AddXY(StatPeopleInModel.LastVal + 1,CurrentTime);
            if RunProperties.Stats.Items[SpentTime] then
              begin
                (paMessage as TPSMessage).Actor.StatWaiting := TWaitStat.create;
                (paMessage as TPSMessage).Actor.StatWaiting.StartWaiting(MySim.CurrentTime);
              end;
          end;
        paMessage.Code := mcPrichodCM;
        paMessage.Addressee := AgentBoss;
        TAgent(MyAgent).RemoveActor(TPSMessage(paMessage).Actor);
        notice(paMessage);
      end;

    end;
end;

{ TAgentEnviroment }

constructor TAgentEnviroment.create(paID: Cardinal; paSim: TSimulation;paParent:TAgent);
begin
  inherited create(paID,paSim,paParent);
  TManagerEnviroment.create(IDManazerOkolia,self,NoMOPN);
  aSchedulerPedestrianArrivals := TSchedulerPedestrianArrivals.create(IDPlanovacPrichoduChodcov,self);
  AddOwnMessage(mcInitO);
  AddOwnMessage(mcOdchodCM);
  AddOwnMessage(mcPrichodC);
end;

{ TPlanovacPrichoduChodcov }

constructor TSchedulerPedestrianArrivals.create(paID: Cardinal; paAgent: TAgent);
begin
  inherited create(paID,paAgent,NoMOPN);
  aActorID := 0;
end;

procedure TSchedulerPedestrianArrivals.ProcessMessage(var paMessage: TMessageForm);
var
  msg: TPSMessage;
  arrival: TArrivalsManager.TArrivalType;
  time: Double;
  j: Integer;
  ped: TPedestrian;
begin
  case paMessage.Code of

    mcStart: begin
      for arrival in (MySim as TPedSimulation).Arrivals do
        begin
          //if not(arrival.Active) then continue;
          msg := paMessage.CreateCopy as TPSMessage;
          msg.Arrival := arrival;
          msg.Code := mcNovy;
          hold(arrival.ArrivesFrom,msg);
          (MySim as TPedSimulation).logMessage('novy prichod: ' + arrival.Name);
        end;
      paMessage.Free;
    end;

    mcNovy: begin
      arrival := (paMessage as TPSMessage).Arrival;
      if MySim.CurrentTime <= arrival.ArrivesTo then
      for j := 0 to arrival.PeopleToArrive - 1 do
        begin
          msg := paMessage.CreateCopy as TPSMessage;
          with msg as TPSMessage do
            begin
              {if random(MaxInt) mod 2 = 0
                then Actor := TPedActor.Create(MySim,TAgent(MyAgent),atBA,aActorID)
                else Actor := TPedActor.Create(MySim,TAgent(MyAgent),atSS,aActorID);}
              Actor := TPedActor.Create(MySim,tAgent(MyAgent),arrival.PedType,aActorID);

              //Actor := TPedActor.Create(MySim,TAgent(MyAgent),atSS,aActorID);
              aActorID := aActorID + 1;
              Actor.Path := arrival.Path;
              if Actor.Path.WayPoints.Count > 0
                then begin
                  Actor.Target := Actor.Path.WayPoints.Items[0];
                  Actor.ActId := 0;
                  Actor.TargetMatrix := nil;
                  ped := (MySim as TPedSimulation).World.getLevel(Actor.Target.Level).insertPedestrian(Actor.Target as TSpawn);
                end else begin
                  Actor.Target := nil;
                  Actor.TargetMatrix := nil;
                  ped := TPedestrian.Create;
                end;
              Actor.TickSubscriber := false;
              if ped <> nil
                then begin
                  if Arrival.StatPeople <> nil then Arrival.StatPeople.AddVal(1);
                  Actor.Pedestrian := ped;
                  Actor.Pedestrian.Typ := actor.Typ;
                  Actor.Pedestrian.GroupName := arrival.Pedestrian.Name;
                  Actor.Pedestrian.CrowdTightning := arrival.Pedestrian.CrowdTightning;
                  Actor.Pedestrian.GainTightning := arrival.Pedestrian.GainTightning;
                  Actor.Pedestrian.BarrierTightning := arrival.Pedestrian.BarierTightning;
                  Actor.Pedestrian.Diameter := arrival.Pedestrian.Diameter;
                  //Actor.Pedestrian.Velocity := arrival.Pedestrian.Velocity;
                  Actor.Pedestrian.MaxVelocity := arrival.Pedestrian.MaxVelocity;
                  Actor.Pedestrian.MaxAcceleration := arrival.Pedestrian.MaxAcceleration;
                  Actor.Pedestrian.View := arrival.Pedestrian.View;
                  msg.Addressee := MyAgent;
                  msg.Code := mcPrichodC;
                  notice(msg);
                end else begin
                  Actor.Path := nil;
                  Actor.Target := nil;
                  Actor.TargetMatrix := nil;
                  Actor.Free;
                  msg.Free;
                end;
            end;
        end;
      time := (paMessage as TPSMessage).Arrival.NextArrival;
      if MySim.CurrentTime + time > (paMessage as TPSMessage).Arrival.ArrivesTo
        then paMessage.Free
        else hold(time,paMessage);
    end; //mcNovy

  end;
end;

end.
